
/*
Copyright 2009 Peter Ekler, Akos Ludanyi, Budapest University of Technology and Economics, Department of Automation and Applied Informatics, Applied Mobile Research Group (AMORG) http://amorg.aut.bme.hu

This file is part of MobTorrent.

MobTorrent is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MobTorrent is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MobTorrent.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ui;

import TorrentEngine.MTBitfield;
import TorrentEngine.MTStringFormatter;
import TorrentEngine.MTTorrent;
import data.LocalizationSupport;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author Tyrael
 */
public class MTCanvasDownloadState extends Canvas implements CommandListener
{
    public static final int ScreenID = 3;

    private final Font SMALL = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_SMALL);
    private final int borderMargin = 5;
    private final int bottomMargin = 10;
    private final int startTextHeight = 3;
    private final int downloadBoxY = startTextHeight+ 5 *(SMALL.getHeight()+3)+2;
    private int downloadBoxHeight = 0;
    private int downloadBoxWidth = 0;
    private int downloadBoxX = 0;

    private int pieceBoxSize = 0;
    private int boxNumPerRow = 0;
    private int boxNumPerCol = 0;
    private int boxNum = 0;
    private int[] pixelPieceArray;
    private int[] pieceColorArray;
    private int pieceCount = 0;
    private MTUIManager uiManager = null;
    private MTTorrent torrent = null;
    private MTBitfield bitField = null;

    private String torrentname = "";
    private String size = "";
    private String downloadpercent = "";
    private Command command_Back;

    private String speed = "";
    private String conn = "";
    private String seedLeech = "";

    /** Creates a new instance of MyCanvas */
    public MTCanvasDownloadState(String aTitle, MTUIManager aUIManager)
    {
        super();
        setTitle(aTitle);
        uiManager = aUIManager;
        setFullScreenMode(false);
        command_Back = new Command(LocalizationSupport.getMessage("command_back"), Command.BACK, 0);
        addCommand(command_Back);
        setCommandListener(this);
    }

    public void commandAction(Command c, Displayable d)
    {
        if (c == command_Back)
        {
            uiManager.showScreen(MTListTorrents.ScreenID);
        }
    }

    public void updateDownloadPercent(double aPercent)
    {
        downloadpercent = MTStringFormatter.getFormattedPercent(aPercent);
        repaint();
    }

     public void updateDownloadSpeed(double aDownloadSpeed, double aUploadSpeed)
    {
        speed = LocalizationSupport.getMessage("text_down")+": "+
            MTStringFormatter.getFormattedFileLength((long)aDownloadSpeed)+"/"+
            LocalizationSupport.getMessage("text_sec")+" "+
            LocalizationSupport.getMessage("text_up")+": "+MTStringFormatter.getFormattedFileLength((long)aUploadSpeed)+"/"+
            LocalizationSupport.getMessage("text_sec");
        repaint();
    }

    public void updateConnections(int aConn, int aInConn)
    {
        conn = ""+aConn+" ("+torrent.getAllPeersNum()+")" + " "+
            LocalizationSupport.getMessage("text_in")+": "+aInConn;
        repaint();
    }

    public void updateSeederLeecher()
    {
        int s = 0;
        int l = 0;
        
        if(torrent != null)
        {
            s = torrent.getSeedersNumber();
            l = torrent.getLeechersNumber();
        }

        seedLeech = "Seeders/Leechers: " + s + "/" + l;
    }

    public void updatePieceDownload()
    {
        calculatePieceColorArray();
        repaint();
    }

    public void initialize(MTTorrent aTorrent)
    {
        torrent = aTorrent;
        //torrentname = torrent.getName();
        torrentname = torrent.getTorrentNameWithoutPath();
        size = MTStringFormatter.getFormattedFileLength(torrent.size());

        downloadpercent = MTStringFormatter.getFormattedPercent(torrent.getDownloadPercent());

        speed = LocalizationSupport.getMessage("text_down")+": "+
            MTStringFormatter.getFormattedFileLength((long)aTorrent.getAvarageBytesPerSecond())+"/"+
            LocalizationSupport.getMessage("text_sec")+" "+
            LocalizationSupport.getMessage("text_up")+": "+
            MTStringFormatter.getFormattedFileLength((long)aTorrent.getAvarageUploadedBytesPerSecond())+"/"+
            LocalizationSupport.getMessage("text_sec");

        conn = ""+torrent.getPeerWireConnectionCount()+" ("+torrent.getAllPeersNum()+")" + " "+
            LocalizationSupport.getMessage("text_in")+": "+torrent.getIncomingConnectionsNum();

        pieceCount = torrent.pieceCount();
        bitField = torrent.getBitField();

        initializeDownloadBox();
        calculatePixelPieceArray();
        calculatePieceColorArray();
    }

    private void initializeDownloadBox()
    {
        int box = 6;
        boolean ok = true;
        int tempDownloadBoxWidth = getWidth()-borderMargin*2;
        int tempDownloadBoxHeight = getHeight()-downloadBoxY-bottomMargin;

        while (ok)
        {
            if (tempDownloadBoxWidth/box>35 || box<12)
            {
                box++;
            }
            else
                ok = false;
        }

        pieceBoxSize = box;
        boxNumPerRow = tempDownloadBoxWidth/pieceBoxSize;
        downloadBoxWidth = boxNumPerRow*pieceBoxSize+1;
        boxNumPerCol = tempDownloadBoxHeight/pieceBoxSize;
        downloadBoxHeight = boxNumPerCol*pieceBoxSize+1;
        boxNum=boxNumPerCol*boxNumPerRow;
        downloadBoxX = getWidth()/2-downloadBoxWidth/2;
    }

    private void calculatePixelPieceArray()
    {
        pixelPieceArray = null;
        pieceColorArray = null;

        int tempSum;
        int piece;

        pixelPieceArray = new int[boxNum];

        pieceColorArray = new int[boxNum];
        for (int i=0; i<boxNum; i++)
            pieceColorArray[i] = -1;

        tempSum=0;
        if (pieceCount<=boxNum)
        {
            piece=0;
            for(int i=0;i<boxNum;i++)
            {
                tempSum+=pieceCount;
                if (tempSum>boxNum)
                {
                    piece++;
                    tempSum-=boxNum;
                }
                pixelPieceArray[i]=piece;
            }
        }
        else
        {
            for(int i=0;i<boxNum;i++)
            {
                pixelPieceArray[i]=((i+1)*pieceCount-tempSum) / boxNum;
                tempSum+=boxNum*pixelPieceArray[i];
            }
        }
    }

    private void calculatePieceColorArray()
    {
        for (int i=0; i<boxNum; i++)
                pieceColorArray[i] = -1;

        if (pieceCount <= boxNum)
        {
                for(int i=0;i<pieceCount;i++)
                {
                    if (bitField.isBitSet(i))
                    {
                        for(int j=0;j<boxNum;j++)
                        {
                            if (pixelPieceArray[j]==i)
                            {
                                pieceColorArray[j] = 1000;
                            }
                        }
                    }
                }
        }
        else
        {
                int currentBit = 0;
                int tempDepth = 0;
                int greenDepth = 0;
                boolean allPieceInPixel = true;

                for (int i=0; i<boxNum; i++)
                {
                    allPieceInPixel = true;
                    tempDepth = 195 / pixelPieceArray[i];
                    greenDepth = 255;

                    for (int j=0; j<pixelPieceArray[i]; j++)
                    {
                        if (bitField.isBitSet(currentBit+j))
                        {
                            pieceColorArray[i] = greenDepth;
                            greenDepth -= tempDepth;
                        }
                        allPieceInPixel = allPieceInPixel && bitField.isBitSet(currentBit+j);
                    }

                    if (allPieceInPixel)
                    {
                        pieceColorArray[i] = 1000;
                    }
                    currentBit += pixelPieceArray[i];
                }
        }
    }

    public void paint(Graphics g)
    {
        g.setFont(SMALL);
        g.setColor(0xd6fff0);
        g.fillRect(0, 0, getWidth(), getHeight());

        g.setColor(0x333333);
        g.drawString(LocalizationSupport.getMessage("label_size")+" "+
            size,5,startTextHeight,Graphics.TOP | Graphics.LEFT);
        if (torrent.isEndGame())
            g.drawString(LocalizationSupport.getMessage("label_downloadpercent")+" "+
                downloadpercent+" - eg     ",5,startTextHeight+SMALL.getHeight()+3,Graphics.TOP | Graphics.LEFT);
        else
            g.drawString(LocalizationSupport.getMessage("label_downloadpercent")+" "+
                downloadpercent+"     ",5,startTextHeight+SMALL.getHeight()+3,Graphics.TOP | Graphics.LEFT);
        g.drawString(speed,5,startTextHeight+2*(SMALL.getHeight()+3),Graphics.TOP | Graphics.LEFT);
        g.drawString(LocalizationSupport.getMessage("label_activeconnections")+" "+
            conn,5,startTextHeight+3*(SMALL.getHeight()+3),Graphics.TOP | Graphics.LEFT);

        updateSeederLeecher();
        g.drawString(seedLeech, 5, startTextHeight + 4 * (SMALL.getHeight() + 3), Graphics.TOP | Graphics.LEFT);

        g.setColor(0,0,0);
        g.drawRect(downloadBoxX,downloadBoxY,downloadBoxWidth,downloadBoxHeight);

        for (int i=0; i<boxNum; i++)
        {
            if (pieceColorArray[i] >=0)
            {
                if (pieceColorArray[i] > 255)
                    g.setColor(0,180,0);
                else
                    g.setColor(pieceColorArray[i],0,0);

                int x = downloadBoxX+1+(i % boxNumPerRow)*pieceBoxSize;
                int y = downloadBoxY+1+(i / boxNumPerRow)*pieceBoxSize;
                g.fillRect(x,y,pieceBoxSize,pieceBoxSize);
            }
        }
    }
}




